/*
 * The MIT License
 *
 * Copyright (c) 2010, Marc Schwerdtfeger (marc@schwerdtfeger.de)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.loosix.core.modules.runtimemoduleloader.impl
{
import flash.events.Event;
import flash.system.ApplicationDomain;

import org.loosix.core.Loosix;
import org.loosix.core.module.Module;
import org.loosix.core.module.impl.AbstractModule;
import org.loosix.core.modules.runtimemoduleloader.*;
import org.loosix.core.modules.runtimemoduleloader.error.RuntimeModuleLoaderError;
import org.loosix.core.utils.ModuleUtil;

public class RuntimeModuleLoaderImpl extends AbstractModule implements RuntimeModuleLoader
    {                     
        public function RuntimeModuleLoaderImpl()
        {
            super(ModuleUtil.getInterfaceName(RuntimeModuleLoader),"Loosix Runtime Module Loader");
        } // endConstructor

        public function loadModule(url:String, implClassName:String):void
        {
            loadModules(url,[implClassName]);
        } // endFunc

        public function loadModules(url:String, implClassNames:Array):void
        {
             var loader:ModuleLoader = new ModuleLoader(url,implClassNames);
             loader.addEventListener(Event.COMPLETE,moduleLoadedHandler);
             loader.load();
        } // endFunc

        private function moduleLoadedHandler(event:Event):void
        {
            var loader:ModuleLoader = event.target as ModuleLoader;
            var domain:ApplicationDomain = loader.data.loaderInfo.applicationDomain;
            var module:Module;

            for each(var implClassName:String in loader.implClassNames)
            {
                if (!domain.hasDefinition(implClassName))
                {
                    throw new RuntimeModuleLoaderError("RuntimeModuleLoaderError: Module Definition '"+implClassName
                                                      +"' not found in file: '"+loader.url+"'",
                                                       RuntimeModuleLoaderError.MODULE_DEFINITION_NOT_FOUND);
                }
                else
                {
                    module = new (domain.getDefinition(implClassName)) as Module;
                    if(module == null)
                    {
                        throw new RuntimeModuleLoaderError("RuntimeModuleLoaderError: '"+implClassName+"' is no " +
                                                           "implementation of 'org.loosix.core.module.Module'",
                                                           RuntimeModuleLoaderError.CLASS_IS_NO_MODULE);
                    }
                    else
                    {
                        Loosix.moduleManager.registerModule(module);
                    } // endIf
                } // endFunc
            } // endFor    
            loader.dispose();
        } // endFunc

    } // endClass
    
} // endPackage